package com.my12306.train.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.my12306.common.constant.CommonConstants;
import com.my12306.common.enums.CodeEnum;
import com.my12306.common.model.vo.PageVo;
import com.my12306.common.util.PageUtils;
import com.my12306.common.util.SnowflakeIdWorker;
import com.my12306.common.util.response.ResponseData;
import com.my12306.train.dao.DecreaseDao;
import com.my12306.train.model.entity.DecreaseEntity;
import com.my12306.train.model.entity.RateEntity;
import com.my12306.train.model.entity.ZoneEntity;
import com.my12306.train.model.vo.DecreaseVO;
import com.my12306.train.model.vo.RateVO;
import com.my12306.train.model.vo.ZoneVO;
import com.my12306.train.service.DecreaseService;
import com.my12306.train.service.RateService;
import com.my12306.train.service.ZoneService;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.validation.constraints.NotNull;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import java.util.stream.Collectors;

@Service("decreaseService")
public class DecreaseServiceImpl extends ServiceImpl<DecreaseDao, DecreaseEntity> implements DecreaseService {
    @Resource
    private DecreaseDao decreaseDao;

    @Resource
    private ZoneService zoneService;
    @Resource
    private RateService rateService;
    @Override
    public PageUtils queryTicketDecreaseByPage(PageVo pageVo) {
        pageVo.init();
        List<DecreaseVO> dataList = this.baseMapper.queryTicketDecreaseByPage(pageVo, CommonConstants.LogicDelete.no_delet.getValue());
        Integer total  = this.queryTicketDecreaseCount(pageVo ,CommonConstants.LogicDelete.no_delet.getValue());

        return PageUtils.build(pageVo, dataList, total);
    }

    private Integer queryTicketDecreaseCount(PageVo pageVo,Integer logicDelete){
     return   this.baseMapper.queryTicketDecreaseCount(pageVo,logicDelete);
    }
    @Override
    public DecreaseVO queryTicketDecreaseById(Long id) {
       return this.baseMapper.queryTicketDecreaseById(id,CommonConstants.LogicDelete.no_delet.getValue());
    }

    @Transactional
    @Override
    public void removeTicketDecreaseByIds(List<Long> ids) {
        if (ids!=null&&ids.size()>0){
            this.baseMapper.deleteBatchTicketDecreaseByIds(ids,CommonConstants.LogicDelete.delete.getValue());
        }
    }

    @Override
    public ResponseData updateTicketDecreaseById(DecreaseEntity decrease) {
        if (decrease!=null&&decrease.getId()!=null){
            decrease.setUpdateDate(new Date());
            //todo  计算递减率
            this.baseMapper.updateById(decrease);
            return ResponseData.ok();
        }else{
            return ResponseData.fail(CodeEnum.UPDATE_FAIL.getCode(),"修改失败！原因：参数不正确！");
        }
    }

    /**
     * 添加递元递减率
     * 1.判断是否是基础票率
     * 1.1不是基础票率，找出该票种的基础票率，然后计算出递减率，
     * 1.2 计算累计区段计算票价。
     * @param decrease
     * @return
     */
    @Override
    @Transactional
    public ResponseData saveTicketDecrease(DecreaseEntity decrease) {
        //1.先查找该票种的所有递减数据然后进行相关判断
        @NotNull Long rateId = decrease.getRateId();
        List<DecreaseVO>decreasVos =queryTicketDecreaseByRateId(rateId);
        //查询 区段
        ZoneEntity zoneEntity = this.zoneService.queryZoneById(decrease.getZoneId());
        RateEntity rate = this.rateService.queryTicketRateById(decrease.getRateId());
        double zoneFrom = zoneEntity.getZoneFrom();
        double zoneTo = zoneEntity.getZoneTo();
        double distance = zoneTo-zoneFrom+1;
        decrease.setId(SnowflakeIdWorker.generateId());
        decrease.setUpdateDate(new Date());
        decrease.setCreateDate(new Date());
        BigDecimal zonePrice = calePrice(distance,rate.getTicketRate(),decrease.getDecreaseRate());
        decrease.setZonePrice(zonePrice);

        decrease.setTicketRate((1-decrease.getDecreaseRate()*0.01)*rate.getTicketRate());
        if (decreasVos==null||decreasVos.size()==0){
            ZoneEntity minZone = zoneService.queryZoneMinByZoneFrom();
            if (minZone!=null){
                if (minZone.getZoneFrom().equals(zoneFrom)) {
                    decrease.setTotalPrice(zonePrice);
                }else{
                    return ResponseData.fail(CodeEnum.ADD_FAIL.getCode(),"添加失败，原因：请先添加首段递远递减率数据！");
                }
            }else{
                return ResponseData.fail(CodeEnum.ADD_FAIL.getCode(),"添加失败，原因：请先添加区段！");
            }
        }else {
            //判断有没有上一段
            AtomicBoolean atomicBoolean = new AtomicBoolean(false);
            AtomicReference<BigDecimal>  totalPrice =new AtomicReference<BigDecimal>(new BigDecimal(0));
            List<DecreaseVO> collect = decreasVos.stream().filter(x -> {

                if (x.getZoneTo().equals(zoneTo) && x.getZoneFrom().equals(zoneFrom)) {
                    return true;
                } else if (x.getZoneTo().equals(zoneFrom - 1)){
                    totalPrice.compareAndSet(totalPrice.get(),x.getTotalPrice());
                    atomicBoolean.compareAndSet( atomicBoolean.get(),true);
                    return false;
                }else{
                    return false;
                }
            }).collect(Collectors.toList());
            if (collect!=null&&collect.size()>0 || !atomicBoolean.get() && decreasVos.size()>0){
               return ResponseData.fail(CodeEnum.ADD_FAIL.getCode(),"添加失败，原因：该递远递减率数据已经存在或者上一区段的递远递减率没添加请先添加上一区段！");
            }else{
                BigDecimal bigDecimal = totalPrice.get();
                BigDecimal add = totalPrice.get().add(zonePrice);
                decrease.setTotalPrice(add);
            }
        }
//        this.baseMapper.insert(decrease);
        this.baseMapper.saveTickDecrease(decrease);
        return ResponseData.ok();
    }

    private BigDecimal calePrice(double distance,double rate,double decresatRate ){
       return new BigDecimal(distance*rate*(1-decresatRate*0.01));
    }
    private List<DecreaseVO>queryTicketDecreaseByRateId(long rateId){
      return   this.baseMapper.queryTicketDecreaseByRateId(rateId,CommonConstants.LogicDelete.no_delet.getValue());
    }

    /**
     * 请求表单参数
     * 1. 请求所以区段信息
     * 2.请求所以票种信息
     * @return
     */
    @Override
    public ResponseData queryTicketDecreaseParams() {
       List<RateVO>rateVOList =  rateService.queryAllTicketRate(CommonConstants.LogicDelete.no_delet.getValue());
       List<ZoneVO>zoneVOList =  zoneService.queryAllZone(CommonConstants.LogicDelete.no_delet.getValue());
        List<ZoneVO> result = zoneVOList.parallelStream().map(x -> {
            BigDecimal zoneFrom = x.getZoneFrom();
            BigDecimal zoneTo = x.getZoneTo();
            StringBuffer stb = new StringBuffer();
            stb.append(zoneFrom).append("-").append(zoneTo);
            x.setMergeZone(stb.toString());
            return x;
        }).distinct().collect(Collectors.toList());
        ResponseData put = ResponseData.ok().put("rateList", rateVOList).put("zoneList", result);
        return put;
    }

    @Override
    public List<DecreaseEntity> queryAllDecreaseById(Long id) {
        QueryWrapper<DecreaseEntity> qs = new QueryWrapper<>();
        if (id != null) {
            qs.eq("rate_id", id);
            qs.eq("logic_delete",CommonConstants.LogicDelete.no_delet.getValue());
        }
        return decreaseDao.selectList(qs);
    }


}
